home *** CD-ROM | disk | FTP | other *** search
- /* tiff.c - routines that parse tiff files
- *
- * Created 88-10-31, out of rev 3.8.
- */
-
- #include "aldtypes.h"
- #include "aldmem.h"
- #include "aldutils.h"
- #include "imtypes.h"
- #include "swap.h"
- #include "immem.h"
- #include "vio.h"
- #include "imag.h"
- #include "imtiff.h"
- #include "tiff.h"
- #include "ImErr.h"
- #include "ImErr2.h" /* application-dependent! for WarningAlert proto and IA_PLACE_IMAGE */
- #include "tiffrout.h"
-
- extern char *ErrorMessages;
-
- #define min(x,y) (((y)<(x)) ? (y) : (x))
- #define MAXBYTE 255
-
-
- /************************ mostly local procedures *************************/
-
-
- /* get data -- handles file/table and byte-order problems
- * 64K max
- */
- RC GtData (pDloc, order, pos, n, dtype, lpData)
- PDLOC pDloc; /* data location - open file or locked-down table */
- WORD order; /* byte order -- INTELTIFF or MOTOROLATIFF */
- DWORD pos; /* file/table position, with respect to its beginning */
- WORD n; /* number of data elements to read */
- WORD dtype; /* data type: TIFFSHORT, etc */
- LPSTR lpData; /* where to put the data */
- {
- RC err;
- WORD tsize;
- WORD BytesToRead;
-
- if (n == 0)
- goto done;
-
- /* read the data
- */
- if (err = GtTiffSizeof (dtype, &tsize)) {
- DBMSG(("GtData: bad dtype\n"));
- return err;
- }
- BytesToRead = tsize * n;
- if (err = VRead (pDloc, pos, BytesToRead, lpData)) {
- DBMSG(("GtData: VRead\n"));
- DBMSG((" err=%u pos=%lu BytesToRead=%u\n",
- err,pos,BytesToRead));
- return err;
- }
-
- /* change the byte order, if necessary
- */
- if (order != MOTOROLATIFF && order != INTELTIFF) {
- DBMSG(("GtData: bad byte order: %u\n", order));
- return IM_BUG; /* should have been caught earlier */
- }
- #ifdef WINDOWS
- if (order == MOTOROLATIFF) {
- #endif
- #ifdef MACINTOSH
- if (order == INTELTIFF) {
- #endif
- if (dtype == TIFFSHORT)
- swab (lpData, lpData, BytesToRead);
- else if (dtype == TIFFLONG)
- swaw (lpData, lpData, BytesToRead);
- else if (dtype == TIFFRATIONAL)
- swaw (lpData, lpData, BytesToRead);
- else if (dtype == TIFFSIGNED)
- swab (lpData, lpData, BytesToRead);
- }
-
- /* return
- */
- done: return SUCCESS;
- }
-
- #define CHUNKSIZE 32768L
-
- /* get a possibly >64K chunk of data, by calling GtData repeatedly
- */
- RC GtHugeData (pDloc, order, pos, dwN, dtype, lpData)
- PDLOC pDloc; /* data location - open file or locked-down table */
- WORD order; /* INTELTIFF or MOTOROLATIFF */
- DWORD pos; /* file/table position, with respect to its beginning */
- DWORD dwN; /* number of data elements to read */
- WORD dtype; /* data type: TIFFSHORT, etc */
- LPSTR lpData; /* where to put the data */
- {
- RC err = SUCCESS;
- WORD tsize;
- DWORD ElementsLeft;
- DWORD ElementsToRead;
- LPSTR lpOut = lpData;
- DWORD ElementsPerChunk;
-
- /* DBMSG(("GtHugeData: top\n")); */
-
- /* get size of elements
- */
- if (err = GtTiffSizeof (dtype, &tsize)) {
- DBMSG(("GtHugeData: bad dtype\n"));
- return err;
- }
-
- /* calculate number of elements per chunk
- */
- ElementsPerChunk = CHUNKSIZE / tsize;
- /* DBMSG((" ElementsPerChunk=%lu\n",ElementsPerChunk)); */
-
- /* read repeatedly
- */
- ElementsLeft = dwN;
- while (ElementsLeft > 0L) {
- ElementsToRead = min (ElementsPerChunk, ElementsLeft);
- /* DBMSG((" ElementsToRead=%lu\n",ElementsToRead)); */
- if (err = GtData (pDloc, order, pos, (WORD)ElementsToRead,
- dtype, lpOut)) {
- DBMSG(("GtHugeData: GtData\n"));
- goto cu;
- }
- lpOut += ElementsToRead * tsize;
- ElementsLeft -= ElementsToRead;
- /* DBMSG((" ElementsLeft=%lu\n",ElementsLeft)); */
- }
- /* DBMSG(("GtHugeData: bottom\n")); */
- cu: return err;
- }
-
- /* get TIFF 8-byte header
- * currently only probably portable. depends somewhat on compiler's
- * structure organization.
- */
- RC GtTiffHdr (pDloc, pHdr)
- PDLOC pDloc;
- register TIFFHDR *pHdr;
- {
- RC err;
-
- /* get the first word -- the byte order.
- * first, set dlOrder to either valid value, since we will immediately
- * change it. sort of a chicken and egg situation.
- */
- /* pDloc->dlOrder = INTELTIFF; */
- if (err = GtData (pDloc, INTELTIFF, (DWORD) 0, 1, TIFFSHORT,
- (LPSTR)&pHdr->thByteOrder)) {
- DBMSG(("GtTiffHdr: A\n"));
- return err;
- }
- /* *pOrder = pHdr->thByteOrder; */
-
- /* get the version
- */
- if (err = GtData (pDloc, pHdr->thByteOrder, (DWORD) 2, 1, TIFFSHORT,
- (LPSTR)&pHdr->thVersion)) {
- DBMSG(("GtTiffHdr: AA\n"));
- return err;
- }
-
- /* get the double word (IFD offset)
- */
- if (err = GtData (pDloc, pHdr->thByteOrder, (DWORD)4, 1, TIFFLONG,
- (LPSTR)&pHdr->thIfdOffset)) {
- DBMSG(("GtTiffHdr: B\n"));
- return err;
- }
- #if 0
- DBMSG(("GtTiffHdr: ByteOrder=%x Version=%u IfdOffset=%lu\n",
- pHdr->thByteOrder, pHdr->thVersion, pHdr->thIfdOffset));
- #endif /* 0 */
-
- /* return
- */
- return SUCCESS;
- }
-
- /* get TIFF directory entry
- */
- RC GtTiffEntry (pDloc, order, EntryOffset, pDe)
- PDLOC pDloc;
- WORD order;
- DWORD EntryOffset;
- register DIRENTRY *pDe;
- {
- RC err;
- DWORD BytesToRead;
- WORD tsize;
- WORD wTmp;
-
- /* get the 2 words beginning with deTag
- */
- if (err = GtData (pDloc, order, EntryOffset, 2, TIFFSHORT,
- (LPSTR)&pDe->deTag)) {
- DBMSG(("GtTiffEntry: A\n"));
- return err;
- }
-
- /* get the 2 dwords, beginning with deLength
- */
- if (err = GtData (pDloc, order, EntryOffset + 4L, 2, TIFFLONG,
- (LPSTR)&pDe->deLength)) {
- DBMSG(("GtTiffEntry: B\n"));
- return err;
- }
-
- /* fix up deVal, if it's not really a LONG
- */
- #ifdef WINDOWS
- if (order == MOTOROLATIFF) {
- #endif
- #ifdef MACINTOSH
- if (order == INTELTIFF) {
- #endif
- if (err = GtTiffSizeof (pDe->deType, &tsize)) {
- DBMSG(("GtTiffEntry: GtTiffSizeof\n"));
- WARN ((HWND)NULL, IM_WARNING, IM_BAD_TTYPE);
- return err;
- }
- BytesToRead = (DWORD)tsize * pDe->deLength;
- if (BytesToRead <= 4) {
- if (tsize == 2) { /* swap words */
- wTmp = * (WORD *) &pDe->deVal;
- * (WORD *) &pDe->deVal = * ((WORD *) &pDe->deVal + 1);
- * ((WORD *) &pDe->deVal + 1) = wTmp;
- }
- else if (tsize == 1) { /* swap bytes */
- swaw ((LPSTR)&pDe->deVal, (LPSTR)&pDe->deVal, 4);
- }
- }
- }
-
- /* return
- */
- return SUCCESS;
- }
-
-
- /* Fill a Tiff Field structure
- * Note: the caller should probably not totally die upon getting an error.
- * Private data types are possible, for one thing. Just don't set the
- * existence flag for the field.
- */
- RC FillTField ARGS((PDLOC,WORD,DIRENTRY *,DWORD,TFIELD *));
- LOCAL RC FillTField (pDloc, order, pDe, EntryOffset, pTF)
- PDLOC pDloc;
- WORD order;
- register DIRENTRY *pDe;
- DWORD EntryOffset;
- register TFIELD *pTF;
- {
- RC err = SUCCESS;
- HANDLE h;
- LPSTR lp;
- WORD TypeSize;
- DWORD BytesToRead;
-
- /* copy tag, type, and length from DIRENTRY structure
- */
- pTF->Texists = TRUE;
- pTF->Ttag = pDe->deTag;
- pTF->Ttype = pDe->deType;
- pTF->Tlength = pDe->deLength;
-
- /* record the offset, for possible later modify-in-place action
- */
- pTF->Tentryoffset = EntryOffset;
-
- /* calculate needed space
- */
- if (err = GtTiffSizeof (pTF->Ttype, &TypeSize)) {
- DBMSG(("FillTField: unknown type\n"));
- goto cu0;
- }
- BytesToRead = (DWORD)TypeSize * pTF->Tlength;
-
- /* if <= 4 bytes, we're almost done. else we have to do some
- * work.
- */
- pTF->Talloc = FALSE; /* just to be safe */
- if (BytesToRead <= 4) {
- pTF->val.Tdword = pDe->deVal;
- }
- else {
-
- /* allocate and lock a buffer
- */
- if (!(h = MMAlloc (BytesToRead))) {
- DBMSG(("FillTField: h\n"));
- err = IM_MEM_FULL;
- goto cu0;
- }
- if (!(lp = MMLock (h))) {
- DBMSG(("FillTField: lp\n"));
- err = IM_MEM_FAIL;
- MMFree (h);
- goto cu0;
- }
-
- /* read the data
- */
- if (err = GtHugeData (pDloc, order, pDe->deVal, pDe->deLength,
- pDe->deType, lp)) {
- DBMSG(("FillTField: GtHugeData\n"));
- MMUnlock (h);
- MMFree (h);
- goto cu0;
- }
-
- /* make sure that the val union contains the first N values from
- * the memory buffer, so that we can use things like p->iBitsPerSample
- * constructs even if there are 3 BitsPerSample values.
- */
- lmemcpy ((LPSTR) &pTF->val.Tchar[0], lp, 4);
-
- /* unlock the buffer
- */
- MMUnlock (h);
-
- /* stuff the handle into the TFIELD structure
- */
- pTF->Thandle = h;
- pTF->Talloc = TRUE;
-
- } /* end of greater-than-4-byte case */
-
- /* return
- */
- cu0: return err;
- }
-
-
- RC TypeConvert ARGS((TFIELD *, WORD));
- LOCAL RC TypeConvert (pTF, totype)
- register TFIELD *pTF;
- WORD totype; /* TIFFBYTE, etc */
- {
- RC err = SUCCESS;
-
- WORD fromtype;
- DWORD dwLength;
-
- WORD SrcSize;
- DWORD SrcBytes;
- DWORD SrcVal;
- LPSTR lpSrc;
-
- WORD DstSize;
- DWORD DstBytes;
- DWORD DstVal;
- LPSTR lpDst;
- HANDLE hDst = (HANDLE)NULL;
-
- /* DBMSG(("TypeConvert: top\n")); */
-
- /* shorthands:
- */
- fromtype = pTF->Ttype;
- dwLength = pTF->Tlength;
-
- /* DBMSG(("tfield:\n"));
- * DBMSG((" Talloc=%u Ttag=%u Ttype=%u Tlength=%lu val=%lx\n",
- * pTF->Talloc,pTF->Ttag,pTF->Ttype,pTF->Tlength,pTF->val.Tdword));
- */
-
- /* if the same type, do nothing
- */
- if (totype == fromtype) {
- goto done;
- }
-
- /* calculate number of source bytes
- */
- if (err = GtTiffSizeof (fromtype, &SrcSize)) {
- DBMSG(("TypeConvert: bad dtype src\n"));
- goto done;
- }
- SrcBytes = (DWORD)SrcSize * dwLength;
-
- /* point to source data
- */
- if (SrcBytes <= (DWORD)4) {
- if (pTF->Talloc) {
- DBMSG(("TypeConvert: size error A\n"));
- err = IM_BUG; /* programming error */
- goto done;
- }
- SrcVal = pTF->val.Tdword;
- lpSrc = (LPSTR)&SrcVal;
- } else {
- if (!pTF->Talloc) {
- DBMSG(("TypeConvert: size error B\n"));
- err = IM_BUG; /* programming error */
- goto done;
- }
- if (pTF->Thandle == (HANDLE)NULL) {
- DBMSG(("TypeConvert: null handle\n"));
- err = IM_BUG; /* programming error */
- goto done;
- }
- if ((lpSrc = MMLock (pTF->Thandle)) == (LPSTR)NULL) {
- DBMSG(("TypeConvert: Thandle\n"));
- err = IM_MEM_FAIL;
- goto done;
- }
- }
-
- /* calculate number of destination bytes
- *
- * In the case of ASCII source and integer or
- * floating point destination, we are going to
- * allocate too much space, and quite possibly
- * allocate when the result would fit into 4
- * bytes, so make sure we take that into consideration
- * below.
- */
- if (err = GtTiffSizeof (totype, &DstSize)) {
- DBMSG(("TypeConvert: bad dtype dst\n"));
- if (pTF->Talloc) MMUnlock (pTF->Thandle);
- goto done;
- }
- DstBytes = (DWORD)DstSize * dwLength;
-
- /* point to destination data
- */
- if (DstBytes <= (DWORD)4)
- lpDst = (LPSTR)&DstVal;
- else {
- if (err = GetItLockIt (DstBytes, &hDst,
- (LPBYTE *)&lpDst)) {
- DBMSG(("TypeConvert: hDst\n"));
- if (pTF->Talloc) MMUnlock (pTF->Thandle);
- goto done;
- }
- }
-
- /* convert depending on source and destination type
- */
- {
- /* if TIFFRATIONAL, convert to floating point or
- * integer. Note that I am relaxing the definition
- * of RATIONAL to include negative numbers.
- */
- if (fromtype == TIFFRATIONAL &&
- (totype == TIFFFLOAT || totype == TIFFSIGNED ||
- totype == TIFFSHORT)) {
- register long FAR *lpSrcPtr; /* assumption: long & DWORD are same length */
- register LPSTR lpDstPtr;
- register DWORD dwCnt;
- float FloatVal;
- short ShortVal;
-
- /* set up
- */
- lpSrcPtr = (long FAR *)lpSrc;
- lpDstPtr = lpDst;
-
- /* for each rational...
- */
- for (dwCnt = (DWORD)0; dwCnt < dwLength; dwCnt++) {
-
- /* calculate a float equivalent
- */
- if (*(lpSrcPtr +1) == (DWORD)0) {
- FloatVal = (float)0.0;
- } else {
- FloatVal = (float)*lpSrcPtr / (float)*(lpSrcPtr+1);
- }
-
- /* translate if necessary, and store
- * into the destination array
- */
- if (totype == TIFFFLOAT) {
- *((float FAR *)lpDstPtr) = FloatVal;
- } else {
- if (FloatVal >= (float)0.0) {
- ShortVal = (short)(FloatVal + .5);
- } else {
- /* is this right? */
- ShortVal = (short)(FloatVal - .5);
- }
- }
- if (totype == TIFFSHORT) {
- *((LPWORD)lpDstPtr) = (WORD)ShortVal;
- } else if (totype == TIFFSIGNED) {
- *((short FAR *)lpDstPtr) = ShortVal;
- }
-
- /* increment the pointers
- */
- lpSrcPtr++;
- lpDstPtr += DstSize;
- }
-
- /* make sure that the val section contains the first N values from
- * the destination array
- */
- if (DstBytes > (DWORD)4) {
- lmemcpy ((LPSTR) &pTF->val.Tdword, (LPSTR)lpDst, 4);
- }
-
- /* set the new type
- */
- pTF->Ttype = totype;
-
- } /* end of rational to float/short/WORD section */
-
- /* else if an unsigned integer (TIFFBYTE, TIFFSHORT, or TIFFLONG),
- * do the appropriate conversion. I probably should check for
- * problems when converting to something smaller. TODO.
- */
- else if ((fromtype == TIFFBYTE || fromtype == TIFFSHORT ||
- fromtype == TIFFLONG) &&
- (totype == TIFFBYTE || totype == TIFFSHORT ||
- totype == TIFFLONG)) {
- register LPSTR lpSrcPtr = lpSrc;
- register LPSTR lpDstPtr = lpDst;
- register DWORD dwCnt;
- register WORD TiffShort;
- register DWORD TiffLong;
-
- if (fromtype == TIFFBYTE && totype == TIFFSHORT) {
- for (dwCnt = (DWORD)0; dwCnt < dwLength; dwCnt++) {
- *((LPWORD)lpDstPtr) = (WORD)*((LPBYTE)lpSrcPtr);
- lpSrcPtr += SrcSize;
- lpDstPtr += DstSize;
- }
- } else if (fromtype == TIFFBYTE && totype == TIFFLONG) {
- for (dwCnt = (DWORD)0; dwCnt < dwLength; dwCnt++) {
- *((LPDWORD)lpDstPtr) = (DWORD)*((LPBYTE)lpSrcPtr);
- lpSrcPtr += SrcSize;
- lpDstPtr += DstSize;
- }
- } else if (fromtype == TIFFSHORT && totype == TIFFBYTE) {
- for (dwCnt = (DWORD)0; dwCnt < dwLength; dwCnt++) {
- TiffShort = *((LPWORD)lpSrcPtr);
- if (TiffShort > MAXBYTE) {
- TiffShort = MAXBYTE;
- }
- *((LPBYTE)lpDstPtr) = (BYTE)TiffShort;
- lpSrcPtr += SrcSize;
- lpDstPtr += DstSize;
- }
- } else if (fromtype == TIFFSHORT && totype == TIFFLONG) {
- for (dwCnt = (DWORD)0; dwCnt < dwLength; dwCnt++) {
- *((LPDWORD)lpDstPtr) = (DWORD)*((LPWORD)lpSrcPtr);
- lpSrcPtr += SrcSize;
- lpDstPtr += DstSize;
- }
- } else if (fromtype == TIFFLONG && totype == TIFFBYTE) {
- for (dwCnt = (DWORD)0; dwCnt < dwLength; dwCnt++) {
- TiffLong = *((LPDWORD)lpSrcPtr);
- if (TiffLong > MAXWORD) {
- TiffLong = MAXWORD;
- }
- *((LPBYTE)lpDstPtr) = (BYTE)TiffLong;
- lpSrcPtr += SrcSize;
- lpDstPtr += DstSize;
- }
- } else if (fromtype == TIFFLONG && totype == TIFFSHORT) {
- for (dwCnt = (DWORD)0; dwCnt < dwLength; dwCnt++) {
- TiffLong = *((LPDWORD)lpSrcPtr);
- if (TiffLong > MAXWORD) {
- TiffLong = MAXWORD;
- }
- *((LPWORD)lpDstPtr) = (WORD)TiffLong;
- lpSrcPtr += SrcSize;
- lpDstPtr += DstSize;
- }
- }
-
- /* make sure that the val section contains the first N values from
- * the destination array, so that I can have a 3-valued BitsPerSample
- * (forced to be the same) but still get "the" BitsPerSample value
- * by using the p->iBitsPerSample contruct
- */
- if (DstBytes > (DWORD)4) {
- lmemcpy ((LPSTR) &pTF->val.Tdword, (LPSTR)lpDst, 4);
- }
-
- /* set the new type
- */
- pTF->Ttype = totype;
- } /* end of unsigned section */
-
- /* else if none of the above cases, give up.
- */
- else {
- DBMSG(("TypeConvert: type problem. fromtype=%d totype=%d\n",
- fromtype, totype));
- if (pTF->Talloc) MMUnlock (pTF->Thandle);
- if (hDst) {
- UnlockItFreeIt (hDst);
- hDst = (HANDLE) NULL;
- }
- err = IM_BUG; /* programming error */
- goto done;
- }
-
- } /* end of conversion section */
-
- /* if neither the source nor destination is allocated,
- * just copy into the 4-byte value
- */
- if (!pTF->Talloc && !hDst) {
- pTF->val.Tdword = DstVal;
- }
-
- /* else if source and destination are both allocated,
- * free the old buffer, and store the new destination handle
- */
- else if (pTF->Talloc && hDst) {
- UnlockItFreeIt (pTF->Thandle);
- pTF->Thandle = hDst;
- MMUnlock (hDst);
- }
-
- /* else if destination is allocated, but not the source,
- * just store the new destination handle
- */
- else if (!pTF->Talloc && hDst) {
- pTF->Thandle = hDst;
- MMUnlock (pTF->Thandle);
- pTF->Talloc = TRUE;
- }
-
- /* else if source is allocated, but not the destination,
- * unlock and free the buffer, and copy the value.
- */
- else if (pTF->Talloc && !hDst) {
- UnlockItFreeIt (pTF->Thandle);
- pTF->Talloc = FALSE;
- pTF->val.Tdword = DstVal;
- }
-
- /* return
- */
- done: return err;
- }
-
-
- /* check for bad values, convert from one format to another
- * if necessary, and store the information in the appropriate
- * TFIELD structure in the IMAG structure
- */
- RC NicefyTField ARGS((TFIELD *, IMAG *));
- RC NicefyTField (pTF, x)
- register TFIELD *pTF;
- register IMAG *x;
- {
- RC err = SUCCESS;
- register WORD Tag;
-
- Tag = pTF->Ttag;
- /* DBMSG(("Nicefy: unsigned tag=%u signed tag=%d\n",
- * pTF->Ttag, pTF->Ttag));
- */
-
- if (Tag == TGNEWSUBFILETYPE) {
- if (err = TypeConvert (pTF, TIFFLONG))
- goto cu0;
- pTF->Texists = TRUE;
- x->tf[X_NEWSUBFILETYPE] = *pTF; /* structure copy */
-
- } else if (Tag == TGIMAGEWIDTH) {
- if (err = TypeConvert (pTF, TIFFSHORT))
- goto cu0;
- pTF->Texists = TRUE;
- x->tf[X_IMAGEWIDTH] = *pTF; /* structure copy */
-
- } else if (Tag == TGIMAGELENGTH) {
- if (err = TypeConvert (pTF, TIFFSHORT))
- goto cu0;
- pTF->Texists = TRUE;
- x->tf[X_IMAGELENGTH] = *pTF; /* structure copy */
-
- } else if (Tag == TGBITSPERSAMPLE) {
- if (err = TypeConvert (pTF, TIFFSHORT))
- goto cu0;
- pTF->Texists = TRUE;
- x->tf[X_BITSPERSAMPLE] = *pTF; /* structure copy */
-
- } else if (Tag == TGCOMPRESSION) {
- if (err = TypeConvert (pTF, TIFFSHORT))
- goto cu0;
- pTF->Texists = TRUE;
- x->tf[X_COMPRESSION] = *pTF; /* structure copy */
-
- } else if (Tag == TGPHOTOMETRICINTERPRETATION) {
- if (err = TypeConvert (pTF, TIFFSHORT))
- goto cu0;
- pTF->Texists = TRUE;
- x->tf[X_PHOTOMETRICINTERP] = *pTF; /* structure copy */
-
- } else if (Tag == TGSTRIPOFFSETS) {
- if (err = TypeConvert (pTF, TIFFLONG))
- goto cu0;
- pTF->Texists = TRUE;
- x->tf[X_STRIPOFFSETS] = *pTF; /* structure copy */
-
- } else if (Tag == TGSAMPLESPERPIXEL) {
- if (err = TypeConvert (pTF, TIFFSHORT))
- goto cu0;
- pTF->Texists = TRUE;
- x->tf[X_SAMPLES] = *pTF; /* structure copy */
-
- } else if (Tag == TGSTRIPBYTECOUNTS) {
- if (err = TypeConvert (pTF, TIFFLONG))
- goto cu0;
- pTF->Texists = TRUE;
- x->tf[X_STRIPBYTECOUNTS] = *pTF; /* structure copy */
-
- } else if (Tag == TGROWSPERSTRIP) {
- if (err = TypeConvert (pTF, TIFFSHORT))
- goto cu0;
- pTF->Texists = TRUE;
- x->tf[X_ROWSPERSTRIP] = *pTF; /* structure copy */
-
- } else if (Tag == TGXRESOLUTION) {
- if (err = TypeConvert (pTF, TIFFFLOAT))
- goto cu0;
- pTF->Texists = TRUE;
- x->tf[X_XRESOLUTION] = *pTF; /* structure copy */
- if (x->fXResolution == (float)0.0)
- x->fXResolution = (float)300.0;
-
- } else if (Tag == TGYRESOLUTION) {
- if (err = TypeConvert (pTF, TIFFFLOAT))
- goto cu0;
- pTF->Texists = TRUE;
- x->tf[X_YRESOLUTION] = *pTF; /* structure copy */
- if (x->fYResolution == (float)0.0)
- x->fYResolution = (float)300.0;
-
- } else if (Tag == TGPLANARCONFIGURATION) {
- if (err = TypeConvert (pTF, TIFFSHORT))
- goto cu0;
- #if 0
- pTF->Texists = TRUE;
- x->tf[X_PLANAR] = *pTF; /* structure copy */
- #endif
-
- } else if (Tag == TGGRAYUNIT) {
- if (err = TypeConvert (pTF, TIFFSHORT))
- goto cu0;
- pTF->Texists = TRUE;
- x->tf[X_GRAYUNIT] = *pTF; /* structure copy */
-
- } else if (Tag == TGGRAYCURVE) {
- if (err = TypeConvert (pTF, TIFFSHORT))
- goto cu0;
- pTF->Texists = TRUE;
- x->tf[X_GRAYCURVE] = *pTF; /* structure copy */
-
- } else if (Tag == TGRESOLUTIONUNIT) {
- if (err = TypeConvert (pTF, TIFFSHORT))
- goto cu0;
- pTF->Texists = TRUE;
- x->tf[X_RESOLUTIONUNIT] = *pTF; /* structure copy */
-
- } else if (Tag == TGPREDICTOR) {
- if (err = TypeConvert (pTF, TIFFSHORT))
- goto cu0;
- pTF->Texists = TRUE;
- x->tf[X_PREDICTOR] = *pTF; /* structure copy */
-
- } else {
- /* DBMSG(("GtTiffInfo: unrecognized tag %d\n",de.deTag)); */
- /*
- * no big deal, probably.
- */
- }
-
- cu0: return err;
- }
-
-
- /************************ exported procedures **********************/
-
- /* read all the TIFF fields that we care about.
- * if from file, it should be open for read.
- * currently, subsequent IFD's are ignored.
- *
- * make sure you fill out the DLOC structure before calling this routine.
- */
- RC GtTiffInfo (pDloc, x)
- PDLOC pDloc; /* table/file input structure */
- register IMAG *x; /* this is where the field information will be put */
- {
- RC err = SUCCESS;
- TIFFHDR th;
- DIRENTRY de;
- TFIELD tf;
- WORD IfdEntries;
- DWORD NextIfd;
- DWORD EntryOffset;
- WORD ii;
- DWORD location;
-
- /* DBMSG(("GtTiffInfo: top\n")); */
-
- /* initialize the structure
- */
- InitImag (x);
-
- /* get the 8-byte header
- */
- if (err = GtTiffHdr (pDloc, &th)) {
- DBMSG(("GtTiffInfo(): can't read header.\n"));
- goto cu0;
- }
- x->iFileType = th.thByteOrder;
- /* pDloc->dlOrder = th.thByteOrder; */
-
- /* check version
- */
- if (th.thVersion != VERSION42) {
- DBMSG(("GtTiffInfo: wrong version\n"));
- err = IM_BUG; /* should have been caught earlier */
- goto cu0;
- }
- x->iVersion = th.thVersion;
-
- /* read the number of directory entries
- */
- if (err = GtData (pDloc, th.thByteOrder, th.thIfdOffset, 1, TIFFSHORT,
- (LPSTR)&IfdEntries)) {
- DBMSG(("GtTiffInfo: can't read # of dir entries\n"));
- goto cu0;
- }
-
- /* loop through the entries
- */
- EntryOffset = th.thIfdOffset + sizeof(IfdEntries);
- for (ii = 0; ii < IfdEntries; ii++, EntryOffset += sizeof(de)) {
-
- /* read the entry
- */
- if (err = GtTiffEntry (pDloc, th.thByteOrder, EntryOffset, &de)) {
- DBMSG(("GtTiffInfo: can't read entry.\n"));
- err = SUCCESS;
- continue;
- }
-
- /* convert to a TFIELD structure, reading big fields as necessary
- */
- if (err = FillTField (pDloc, th.thByteOrder, &de, EntryOffset, &tf)) {
- DBMSG(("GtTiffInfo: FillTField\n"));
- err = SUCCESS;
- continue;
- }
-
- /* check for bad values, convert from one format to another
- * if necessary, and store the information in the appropriate
- * TFIELD structure in the IMAG structure
- */
- if (err = NicefyTField (&tf, x)) {
- DBMSG(("GtTiffInfo: NicefyTField\n"));
- err = SUCCESS;
- continue;
- }
-
- } /* end of direntry loop */
-
- /* check the offset of the next IFD
- */
- {
- DWORD NextIFD;
- WORD Dummy;
-
- if (err = GtData (pDloc, th.thByteOrder, EntryOffset, 1, TIFFLONG,
- (LPSTR)&NextIFD)) {
- DBMSG(("GtTiffInfo: can't read next-IFD-offset\n"));
- err = IM_BAD_NEXT_IFD;
- goto cu0;
- }
- if (err = GtData (pDloc, th.thByteOrder, NextIFD, 1, TIFFSHORT,
- (LPSTR)&Dummy)) {
- DBMSG(("GtTiffInfo: can't read next IFD\n"));
- err = IM_BAD_NEXT_IFD;
- goto cu0;
- }
- }
-
- /* miscellaneous correctness checks
- */
- if (err = CheckTiff (x)) {
- /* DBMSG((" CheckTiff\n")); */
- goto cu0;
- }
-
- /* return
- */
- cu0: return err;
- }